package com.duojuhe.coremodule.form.service.impl;

import com.duojuhe.cache.SystemDictCache;
import com.duojuhe.common.annotation.DataScopeFilter;
import com.duojuhe.common.annotation.KeyLock;
import com.duojuhe.common.bean.UserTokenInfoVo;
import com.duojuhe.common.enums.SystemEnum;
import com.duojuhe.coremodule.form.enums.FormEnum;
import com.duojuhe.common.exception.base.DuoJuHeException;
import com.duojuhe.common.result.ErrorCodes;
import com.duojuhe.common.result.PageResult;
import com.duojuhe.common.result.ServiceResult;
import com.duojuhe.common.utils.encryption.md5.MD5Util;
import com.duojuhe.common.utils.idgenerator.UUIDUtils;
import com.duojuhe.common.utils.page.PageHelperUtil;
import com.duojuhe.coremodule.BaseService;
import com.duojuhe.coremodule.form.entity.FormProject;
import com.duojuhe.coremodule.form.entity.FormProjectItem;
import com.duojuhe.coremodule.form.entity.FormProjectLogic;
import com.duojuhe.coremodule.form.entity.FormProjectStyle;
import com.duojuhe.coremodule.form.mapper.*;
import com.duojuhe.coremodule.form.pojo.project.*;
import com.duojuhe.coremodule.form.pojo.projectitem.QueryFormProjectItemRes;
import com.duojuhe.coremodule.form.pojo.projectstyle.QueryFormProjectStyleRes;
import com.duojuhe.coremodule.form.pojo.projecttemplate.SaveFormProjectTemplateReq;
import com.duojuhe.coremodule.form.pojo.projecttemplate.SaveFormProjectTransferTemplateReq;
import com.duojuhe.coremodule.form.pojo.projecttemplate.UpdateFormProjectTemplateReq;
import com.duojuhe.coremodule.form.service.FormProjectTemplateService;
import com.duojuhe.coremodule.form.utils.handle.HandleFormUtils;
import com.duojuhe.coremodule.system.entity.SystemDict;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
@Slf4j
@Service
public class FormProjectTemplateServiceImpl extends BaseService implements FormProjectTemplateService {
    @Resource
    private SystemDictCache systemDictCache;
    @Resource
    private FormProjectMapper formProjectMapper;
    @Resource
    private FormProjectItemMapper formProjectItemMapper;
    @Resource
    private FormProjectStyleMapper formProjectStyleMapper;
    @Resource
    private FormCategoryMapper formCategoryMapper;
    @Resource
    private FormProjectLogicMapper formProjectLogicMapper;

    /**
     * 【分页查询】根据条件查询表单项目私有模板list
     * @param req
     * @return
     */
    @DataScopeFilter
    @Override
    public ServiceResult<PageResult<List<QueryFormProjectPageRes>>> queryFormProjectPrivateTemplatePageResList(QueryFormProjectPageReq req) {
        //查询指定模块
        String projectModule = FormEnum.FormProjectModule.FORM_SURVEY_TEMPLATE.getKey();
        //查询指定类型
        String projectTypeCode = FormEnum.FormProjectType.FORM_SURVEY_PRIVATE_TEMPLATE.getKey();
        PageHelperUtil.orderByAndStartPage(req, "sort desc,createTime desc, projectId desc");
        List<QueryFormProjectPageRes> list = formProjectMapper.queryFormProjectPageResList(req,projectModule,projectTypeCode);
        for (QueryFormProjectPageRes res:list){
            SystemDict statusCode = systemDictCache.getSystemDictByDictCode(res.getStatusCode());
            res.setStatusName(statusCode.getDictName());
            res.setStatusColor(statusCode.getDictColor());
        }
        return PageHelperUtil.returnServiceResult(req, list);
    }

    /**
     * 【分页查询】根据条件查询表单项目公有模板list
     * @param req
     * @return
     */
    @Override
    public ServiceResult<PageResult<List<QueryFormProjectPageRes>>> queryFormProjectPublicTemplatePageResList(QueryFormProjectPageReq req) {
        //查询指定模块
        String projectModule = FormEnum.FormProjectModule.FORM_SURVEY_TEMPLATE.getKey();
        //查询指定类型
        String projectTypeCode = FormEnum.FormProjectType.FORM_SURVEY_PUBLIC_TEMPLATE.getKey();
        req.setDataScopeFilter(null);
        PageHelperUtil.orderByAndStartPage(req, "sort desc,createTime desc, projectId desc");
        List<QueryFormProjectPageRes> list = formProjectMapper.queryFormProjectPageResList(req,projectModule,projectTypeCode);
        for (QueryFormProjectPageRes res:list){
            SystemDict statusCode = systemDictCache.getSystemDictByDictCode(res.getStatusCode());
            res.setStatusName(statusCode.getDictName());
            res.setStatusColor(statusCode.getDictColor());
        }
        return PageHelperUtil.returnServiceResult(req, list);
    }

    /**
     * 【保存】表单项目模板
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult saveFormProjectTemplate(SaveFormProjectTemplateReq req) {
        //检查分类是否存在
        checkFormProjectCategoryId(req.getCategoryId());
        //获取封面
        String coverImg = req.getCoverImg();
        //项目模板id
        String projectId = UUIDUtils.getUUID32();
        //项目模板key
        String projectKey = UUIDUtils.getSequenceNo();
        //当前登录人
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //当前登录人id
        String userId = userTokenInfoVo.getUserId();
        //指定模块
        String projectModule = FormEnum.FormProjectModule.FORM_SURVEY_TEMPLATE.getKey();
        //是
        Integer YES = SystemEnum.IS_YES.YES.getKey();
        //否
        Integer NO = SystemEnum.IS_YES.NO.getKey();
        //当前时间
        Date nowDate = new Date();
        FormProject formProject = new FormProject();
        formProject.setProjectId(projectId);
        formProject.setProjectKey(projectKey);
        formProject.setCategoryId(req.getCategoryId());
        formProject.setCoverImg(coverImg);
        formProject.setProjectName(req.getProjectName());
        formProject.setSort(0);
        formProject.setCreateTime(nowDate);
        formProject.setCreateUserId(userId);
        formProject.setUpdateTime(nowDate);
        formProject.setUpdateUserId(userId);
        formProject.setCreateDeptId(userTokenInfoVo.getCreateDeptId());
        formProject.setTenantId(userTokenInfoVo.getTenantId());
        formProject.setStatusCode(FormEnum.FormProjectStatus.FORM_PROJECT_UNPUBLISHED.getKey());
        formProject.setMaxFormItemId(1L);
        formProject.setMaxFormItemSort(1L);
        formProject.setHits(0L);
        formProject.setProjectModuleCode(projectModule);
        formProject.setProjectTypeCode(FormEnum.FormProjectType.FORM_SURVEY_PRIVATE_TEMPLATE.getKey());
        //构建表单风格对象
        FormProjectStyle formProjectStyle = new FormProjectStyle();
        formProjectStyle.setProjectId(projectId);
        formProjectStyle.setProjectKey(projectKey);
        formProjectStyle.setCreateTime(nowDate);
        formProjectStyle.setCreateUserId(userId);
        formProjectStyle.setUpdateUserId(userId);
        formProjectStyle.setUpdateTime(nowDate);
        formProjectStyle.setShowDescribe(YES);
        formProjectStyle.setShowNumber(YES);
        formProjectStyle.setShowTitle(YES);
        //插入项目模板表
        formProjectMapper.insertSelective(formProject);
        //插入项目模板风格表
        formProjectStyleMapper.insertSelective(formProjectStyle);
        return ServiceResult.ok(projectId);
    }
    /**
     * 【保存】根据项目id转成模板
     * @param req
     * @return
     */
    @KeyLock(lockKeyParts = "projectId")
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult saveFormProjectTransferTemplate(SaveFormProjectTransferTemplateReq req) {
        //检查分类是否存在
        checkFormProjectCategoryId(req.getCategoryId());
        //源项目id
        String sourceProjectId = req.getProjectId();
        //查询项目是否存在
        FormProject formProject = formProjectMapper.selectByPrimaryKey(sourceProjectId);
        if (formProject == null || !FormEnum.FormProjectModule.FORM_SURVEY_PROJECT.getKey().equals(formProject.getProjectModuleCode())) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //查询项目风格
        FormProjectStyle formProjectStyle = formProjectStyleMapper.selectByPrimaryKey(sourceProjectId);
        if (formProjectStyle == null) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //当前登录人id
        String userId = userTokenInfoVo.getUserId();
        //指定模块
        String projectModule = FormEnum.FormProjectModule.FORM_SURVEY_TEMPLATE.getKey();
        //当前时间
        Date nowDate = new Date();
        //项目id
        String projectId = UUIDUtils.getUUID32();
        //项目模板key
        String projectKey = UUIDUtils.getSequenceNo();
        //插入项目模板表
        formProject.setProjectId(projectId);
        formProject.setProjectKey(projectKey);
        formProject.setCoverImg(req.getCoverImg());
        formProject.setProjectName(req.getProjectName());
        formProject.setSort(0);
        formProject.setCategoryId(req.getCategoryId());
        formProject.setCreateTime(nowDate);
        formProject.setCreateUserId(userId);
        formProject.setUpdateTime(nowDate);
        formProject.setUpdateUserId(userId);
        formProject.setCreateDeptId(userTokenInfoVo.getCreateDeptId());
        formProject.setTenantId(userTokenInfoVo.getTenantId());
        formProject.setStatusCode(FormEnum.FormProjectStatus.FORM_PROJECT_UNPUBLISHED.getKey());
        formProject.setHits(0L);
        formProject.setProjectModuleCode(projectModule);
        formProject.setProjectTypeCode(FormEnum.FormProjectType.FORM_SURVEY_PRIVATE_TEMPLATE.getKey());
        formProjectMapper.insertSelective(formProject);
        //插入项目模板风格表
        formProjectStyle.setProjectId(projectId);
        formProjectStyle.setProjectKey(projectKey);
        formProjectStyle.setCreateTime(nowDate);
        formProjectStyle.setCreateUserId(userId);
        formProjectStyle.setUpdateUserId(userId);
        formProjectStyle.setUpdateTime(nowDate);
        formProjectStyleMapper.insertSelective(formProjectStyle);
        //构建子项目
        List<FormProjectItem>  formProjectItemList = formProjectItemMapper.queryFormProjectItemListByProjectId(sourceProjectId);
        if (!formProjectItemList.isEmpty()){
            for (FormProjectItem formProjectItem:formProjectItemList){
                //itemId 是有项目id表单id md5组成
                String itemId = MD5Util.getMD532(projectId+formProjectItem.getFormItemId());
                formProjectItem.setItemId(itemId);
                formProjectItem.setUpdateTime(nowDate);
                formProjectItem.setCreateTime(nowDate);
                formProjectItem.setProjectId(projectId);
                formProjectItem.setProjectKey(projectKey);
            }
            formProjectItemMapper.batchInsertListUseAllCols(formProjectItemList);
        }

        //构建显示逻辑
        List<FormProjectLogic> formProjectLogicList = formProjectLogicMapper.queryFormProjectLogicListByProjectId(sourceProjectId);
        if (!formProjectLogicList.isEmpty()){
            for (FormProjectLogic formProjectLogic:formProjectLogicList){
                String itemId = MD5Util.getMD532(projectId+formProjectLogic.getFormItemId());
                formProjectLogic.setId(itemId);
                formProjectLogic.setProjectId(projectId);
                formProjectLogic.setProjectKey(projectKey);
                formProjectLogic.setItemId(itemId);
                formProjectLogic.setCreateTime(nowDate);
                formProjectLogic.setUpdateTime(nowDate);
            }
            formProjectLogicMapper.batchInsertListUseAllCols(formProjectLogicList);
        }
        return ServiceResult.ok(projectId);
    }


    /**
     * 【修改】表单项目模板
     * @param req
     * @return
     */
    @KeyLock(lockKeyParts = "projectId")
    @Override
    public ServiceResult updateFormProjectTemplate(UpdateFormProjectTemplateReq req) {
        //检查分类是否存在
        checkFormProjectCategoryId(req.getCategoryId());
        //只允许操作私有模板
        String projectType = FormEnum.FormProjectType.FORM_SURVEY_PRIVATE_TEMPLATE.getKey();
        //项目id
        String projectId = req.getProjectId();
        FormProject formProjectOld = formProjectMapper.selectByPrimaryKey(projectId);
        if (formProjectOld == null || !projectType.equals(formProjectOld.getProjectTypeCode())) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //获取封面
        String coverImg = req.getCoverImg();
        //当前登录人id
        String userId = getCurrentLoginUserId();
        //当前时间
        Date nowDate = new Date();
        FormProject formProject = new FormProject();
        formProject.setProjectId(projectId);
        formProject.setCategoryId(req.getCategoryId());
        formProject.setProjectName(req.getProjectName());
        formProject.setCoverImg(coverImg);
        formProject.setUpdateTime(nowDate);
        formProject.setUpdateUserId(userId);
        formProjectMapper.updateByPrimaryKeySelective(formProject);
        return ServiceResult.ok(projectId);
    }

    /**
     * 【删除】根据表单项目模板id删除项目模板
     * @param req
     * @return
     */
    @KeyLock(lockKeyParts = "projectId")
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult deleteFormProjectTemplateByProjectId(FormProjectIdReq req) {
        //只允许操作私有模板
        String projectType = FormEnum.FormProjectType.FORM_SURVEY_PRIVATE_TEMPLATE.getKey();
        //项目id
        String projectId = req.getProjectId();
        FormProject formProjectOld = formProjectMapper.selectByPrimaryKey(projectId);
        if (formProjectOld == null || !projectType.equals(formProjectOld.getProjectTypeCode())) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //删除项目模板
        formProjectMapper.deleteByPrimaryKey(projectId);
        //删除项目模板风格表
        formProjectStyleMapper.deleteByPrimaryKey(projectId);
        return ServiceResult.ok(ErrorCodes.SUCCESS);
    }


    /**
     * 根据项目模板key查询详情
     * @param req
     * @return
     */
    @Override
    @KeyLock(lockKeyParts = "projectId")
    public ServiceResult<QueryFormProjectRes> queryFormProjectTemplateResByProjectId(FormProjectIdReq req) {
        //查询指定模块
        String projectModule = FormEnum.FormProjectModule.FORM_SURVEY_TEMPLATE.getKey();
        //项目id
        String projectId = req.getProjectId();
        QueryFormProjectRes res = formProjectMapper.queryFormProjectResByProjectId(projectId);
        if (res == null  || !projectModule.equals(res.getProjectModuleCode())) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        return ServiceResult.ok(res);
    }

    /**
     * 根据项目模板id查询项目模板明细
     * @param req
     * @return
     */
    @Override
    @KeyLock(lockKeyParts = "projectId")
    public ServiceResult<QueryFormProjectDetailsRes> queryFormProjectTemplateDetailsResByProjectId(FormProjectIdReq req) {
        //查询指定模块
        String projectModule = FormEnum.FormProjectModule.FORM_SURVEY_TEMPLATE.getKey();
        //项目id
        String projectId = req.getProjectId();
        QueryFormProjectRes projectRes = formProjectMapper.queryFormProjectResByProjectId(projectId);
        if (projectRes == null  || !projectModule.equals(projectRes.getProjectModuleCode())) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        QueryFormProjectStyleRes styleRes = formProjectStyleMapper.queryFormProjectStyleResByProjectId(projectId);
        if (styleRes == null) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        QueryFormProjectDetailsRes detailsRes = new QueryFormProjectDetailsRes();
        //项目模板详情
        detailsRes.setFormProjectRes(projectRes);
        //项目模板风格详情
        detailsRes.setFormProjectStyleRes(styleRes);
        //项目模板明细集合
        PageHelperUtil.defaultOrderBy("sort asc,updateTime desc, projectId desc");
        List<QueryFormProjectItemRes> itemResList = formProjectItemMapper.queryFormProjectItemResListByProjectId(projectId);
        for (QueryFormProjectItemRes res:itemResList){
            HandleFormUtils.setHandleFormProjectItemRes(res);
        }
        detailsRes.setFormProjectItemResList(itemResList);
        return ServiceResult.ok(detailsRes);
    }



    /**
     * 【私有方法，辅助其他接口方法使用】 检查表单模板分类是否存在
     */
    private void checkFormProjectCategoryId(String categoryId) {
        if (StringUtils.isBlank(categoryId)){
            throw new DuoJuHeException(ErrorCodes.FORM_PROJECT_CATEGORY_NOT_EXIST);
        }
        if(formCategoryMapper.selectByPrimaryKey(categoryId)==null){
            throw new DuoJuHeException(ErrorCodes.FORM_PROJECT_CATEGORY_NOT_EXIST);
        }
    }
}
